from tortoise import fields, models


class PermissionModel(models.Model):
    """权限模型"""
    
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100, description="权限名称")
    code = fields.CharField(max_length=100, unique=True, description="权限编码")
    type = fields.CharField(max_length=20, default="menu", description="权限类型：menu(菜单), button(按钮), api(接口)")
    parent_id = fields.IntField(default=0, description="父级权限ID")
    path = fields.CharField(max_length=255, null=True, description="路由路径")
    component = fields.CharField(max_length=255, null=True, description="组件路径")
    icon = fields.CharField(max_length=100, null=True, description="图标")
    sort_order = fields.IntField(default=0, description="排序")
    is_visible = fields.BooleanField(default=True, description="是否可见")
    is_active = fields.BooleanField(default=True, description="是否激活")
    is_system = fields.BooleanField(default=False, description="是否系统权限")
    remark = fields.TextField(null=True, description="备注")
    created_at = fields.DatetimeField(auto_now_add=True, description="创建时间")
    updated_at = fields.DatetimeField(auto_now=True, description="更新时间")

    class Meta:
        """模型元数据
        
        - table: 指定数据库表名
        - table_description: 表描述，用于数据库文档
        """
        table = "permissions"
        table_description = "权限表"

    def __str__(self):
        """返回权限的字符串表示，用于调试和显示"""
        return self.name

    async def get_children(self):
        """获取子权限列表
        
        Returns:
            QuerySet: 子权限查询集
        """
        return await self.filter(parent_id=self.id).order_by('sort_order', 'id')

    async def get_parent(self):
        """获取父级权限
        
        Returns:
            PermissionModel: 父级权限对象，如果不存在返回None
        """
        if self.parent_id == 0:
            return None
        return await self.filter(id=self.parent_id).first()

    async def get_ancestors(self):
        """获取所有祖先权限（递归）
        
        Returns:
            List[PermissionModel]: 祖先权限列表
        """
        ancestors = []
        current = self
        while current.parent_id != 0:
            parent = await current.get_parent()
            if parent:
                ancestors.insert(0, parent)
                current = parent
            else:
                break
        return ancestors

    async def get_descendants(self):
        """获取所有后代权限（递归）
        
        Returns:
            List[PermissionModel]: 后代权限列表
        """
        descendants = []
        children = await self.get_children()
        for child in children:
            descendants.append(child)
            descendants.extend(await child.get_descendants())
        return descendants

    def is_menu(self) -> bool:
        """判断是否为菜单权限
        
        Returns:
            bool: 是否为菜单权限
        """
        return self.type == "menu"

    def is_button(self) -> bool:
        """判断是否为按钮权限
        
        Returns:
            bool: 是否为按钮权限
        """
        return self.type == "button"

    def is_api(self) -> bool:
        """判断是否为接口权限
        
        Returns:
            bool: 是否为接口权限
        """
        return self.type == "api"

    @classmethod
    async def get_by_code(cls, code: str):
        """根据权限编码获取权限
        
        Args:
            code: 权限编码
            
        Returns:
            PermissionModel: 权限对象，如果不存在返回None
        """
        return await cls.filter(code=code).first()

    @classmethod
    async def get_root_permissions(cls):
        """获取根级权限（parent_id=0）
        
        Returns:
            QuerySet: 根级权限查询集
        """
        return cls.filter(parent_id=0, is_active=True).order_by('sort_order', 'id')

    @classmethod
    async def get_menus(cls):
        """获取所有菜单权限
        
        Returns:
            QuerySet: 菜单权限查询集
        """
        return cls.filter(type="menu", is_active=True, is_visible=True).order_by('sort_order', 'id')

    @classmethod
    async def get_buttons(cls):
        """获取所有按钮权限
        
        Returns:
            QuerySet: 按钮权限查询集
        """
        return cls.filter(type="button", is_active=True).order_by('sort_order', 'id')

    @classmethod
    async def get_apis(cls):
        """获取所有接口权限
        
        Returns:
            QuerySet: 接口权限查询集
        """
        return cls.filter(type="api", is_active=True).order_by('sort_order', 'id')

    @classmethod
    async def get_system_permissions(cls):
        """获取系统权限
        
        Returns:
            QuerySet: 系统权限查询集
        """
        return cls.filter(is_system=True, is_active=True)

    @classmethod
    async def get_custom_permissions(cls):
        """获取自定义权限
        
        Returns:
            QuerySet: 自定义权限查询集
        """
        return cls.filter(is_system=False, is_active=True)

    @classmethod
    async def get_permission_tree(cls):
        """获取权限树结构
        
        Returns:
            List[Dict]: 权限树结构
        """
        async def build_tree(parent_id=0):
            permissions = await cls.filter(parent_id=parent_id, is_active=True).order_by('sort_order', 'id')
            tree = []
            for permission in permissions:
                node = {
                    'id': permission.id,
                    'name': permission.name,
                    'code': permission.code,
                    'type': permission.type,
                    'path': permission.path,
                    'component': permission.component,
                    'icon': permission.icon,
                    'sort_order': permission.sort_order,
                    'is_visible': permission.is_visible,
                    'children': await build_tree(permission.id)
                }
                tree.append(node)
            return tree
        
        return await build_tree()
